package com.bum.rss.service.helper;

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.task.TaskExecutor;

import com.bum.rss.bo.SiteBO;
import com.bum.rss.exp.om.Rss;
import com.bum.rss.exp.om.RssEntry;

public class PreloadHelper implements ApplicationContextAware {
	static Logger	log			= Logger.getLogger(PreloadHelper.class);

	SiteBO			siteBO;
	TaskExecutor	executor;

	private String	user		= null;
	private int		limitDeep	= 2;

	@Override
	public void setApplicationContext(ApplicationContext arg0) throws BeansException {
		Executors.newScheduledThreadPool(1).scheduleWithFixedDelay(new Runnable() {
			@Override
			public void run() {
				try {
					log.debug("START PRELOAD...");
					preload(null, 0);
					log.debug("FINISH PRELOAD...");
				} catch (Throwable e) {
					log.debug(e.getMessage(), e);
				}
			}
		}, 10, 2700, TimeUnit.SECONDS);
	}

	private void preload(String url, final int deep) {
		if (deep > limitDeep) {
			return;
		}

		Rss rss = siteBO.load(url, user);
		if (rss == null || CollectionUtils.isEmpty(rss.getEntries())) {
			log.debug("Hết..." + deep);
			return;
		}

		for (final RssEntry entry : rss.getEntries()) {
			log.debug("LOAD: " + deep + " " + entry.getUrl());
			if (deep < 2) {
				// one thread for each site
				new Thread(new Runnable() {
					@Override
					public void run() {
						try {
							preload(entry.getUrl(), deep + 1);
							log.debug("ok...");
						} catch (Throwable e) {
							log.debug(e.getMessage(), e);
						}
					}
				}).start();
			} else {
				try {
					preload(entry.getUrl(), deep + 1);
				} catch (Throwable e) {
					log.debug(e.getMessage(), e);
				}
				log.debug("ok...");

				// list cat entries
				try {
					Thread.sleep(1000L);
				} catch (InterruptedException e) {
				}
			}
		}
	}

	public void setSiteBO(SiteBO siteBO) {
		this.siteBO = siteBO;
	}

	public void setLimitDeep(int limitDeep) {
		this.limitDeep = limitDeep;
	}

	public void setExecutor(TaskExecutor executor) {
		this.executor = executor;
	}
}
